import tkinter as tk
from tkinter import messagebox


class Calculator:
    def __init__(self, master):
        self.master = master
        master.title("科学计算器")
        master.geometry("320x450")

        # 初始化变量
        self.current_input = "0"
        self.formula = ""

        # 创建显示区域
        self.create_display()
        # 创建按钮
        self.create_buttons()

    def create_display(self):
        """创建显示区域"""
        # 公式显示行
        self.formula_label = tk.Label(self.master, text=self.formula,
                                      anchor="e", bg="#f0f0f0",
                                      font=("Arial", 15))
        self.formula_label.grid(row=0, column=0, columnspan=4,
                                sticky="nsew", padx=10, pady=10)

        # 输入显示行
        self.input_label = tk.Label(self.master, text=self.current_input,
                                    anchor="e", bg="white",
                                    font=("Arial", 24, "bold"))
        self.input_label.grid(row=1, column=0, columnspan=4,
                              sticky="nsew", padx=10, pady=10)

    def create_buttons(self):
        """创建按钮布局"""
        buttons = [
            ('C', 2, 0), ('±', 2, 1), ('%', 2, 2), ('÷', 2, 3),
            ('7', 3, 0), ('8', 3, 1), ('9', 3, 2), ('×', 3, 3),
            ('4', 4, 0), ('5', 4, 1), ('6', 4, 2), ('-', 4, 3),
            ('1', 5, 0), ('2', 5, 1), ('3', 5, 2), ('+', 5, 3),
            ('0', 6, 0), ('.', 6, 1), ('(', 6, 2), (')', 6, 3),
            ('=', 7, 0, 4)  # 跨4列的等号按钮
        ]

        # 配置按钮样式
        button_config = {
            'font': ('Arial', 16),
            'bd': 1,
            'relief': 'ridge',
            'bg': '#f0f0f0',
            'activebackground': '#d9d9d9'
        }

        # 生成按钮
        for btn in buttons:
            text = btn[0]
            if text == '=':
                btn_obj = tk.Button(self.master, text=text,
                                    command=self.calculate,
                                    **button_config)
                btn_obj.grid(row=btn[1], column=btn[2],
                             columnspan=btn[3], sticky="nsew")
            else:
                btn_obj = tk.Button(self.master, text=text,
                                    command=lambda t=text: self.button_click(t),
                                    **button_config)
                btn_obj.grid(row=btn[1], column=btn[2], sticky="nsew")

        # 配置网格权重
        for i in range(8):
            self.master.grid_rowconfigure(i, weight=1)
        for j in range(4):
            self.master.grid_columnconfigure(j, weight=1)

    def update_display(self):
        """更新显示内容"""
        self.input_label.config(text=self.current_input[-10:])  # 最多显示10位
        self.formula_label.config(text=self.formula)

    def button_click(self, char):
        """处理按钮点击事件"""
        operators = {'+', '-', '×', '÷', '%'}

        # 处理特殊按钮
        if char == 'C':
            self.current_input = "0"
            self.formula = ""
        elif char == '±':
            if self.current_input.startswith('-'):
                self.current_input = self.current_input[1:]
            else:
                self.current_input = '-' + self.current_input
        elif char == '%':
            try:
                self.current_input = str(eval(self.current_input + "/100"))
            except:
                self.show_error("无效百分比运算")
        elif char in operators:
            self.handle_operator(char)
        elif char in ('(', ')'):
            self.handle_brackets(char)
        else:
            self.handle_number(char)

        self.update_display()

    def handle_operator(self, operator):
        """处理运算符输入"""
        # 转换符号显示
        display_operator = operator
        if operator == '×': display_operator = '*'
        if operator == '÷': display_operator = '/'

        # 检查前一个字符是否是运算符
        if self.current_input and self.current_input[-1] in {'+', '-', '*', '/'}:
            self.current_input = self.current_input[:-1] + display_operator
        else:
            self.formula += self.current_input
            self.current_input = display_operator

    def handle_number(self, num):
        """处理数字输入"""
        if self.current_input == "0":
            if num == '.':
                self.current_input = "0."
            else:
                self.current_input = num
        else:
            # 防止重复小数点
            if num == '.' and '.' in self.current_input:
                return
            self.current_input += num

    def handle_brackets(self, bracket):
        """处理括号输入"""
        if bracket == '(':
            self.formula += self.current_input + '('
            self.current_input = "0"
        elif bracket == ')':
            self.formula += self.current_input + ')'
            self.current_input = "0"

    def calculate(self):
        """执行计算"""
        try:
            # 替换显示符号为实际运算符
            expression = (self.formula + self.current_input).replace('×', '*').replace('÷', '/')
            result = str(eval(expression))

            # 显示计算过程
            self.formula = expression + "="
            self.current_input = result
            self.update_display()

            # 重置为初始状态
            self.formula = ""
        except Exception as e:
            self.show_error(f"计算错误: {str(e)}")
            self.current_input = "0"
            self.formula = ""
            self.update_display()

    def show_error(self, message):
        """显示错误提示"""
        messagebox.showerror("错误", message)


if __name__ == "__main__":
    root = tk.Tk()
    app = Calculator(root)
    root.mainloop()
